﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace Gmantis.Controls
{
    [TemplatePart(Name = "Increase", Type = typeof(RepeatButton)), 
    TemplatePart(Name = "Decrease", Type = typeof(RepeatButton)), 
    TemplateVisualState(Name = "ShowButtons", GroupName = "ButtonsVisibilityStates"), 
    TemplateVisualState(Name = "HideButtons", GroupName = "ButtonsVisibilityStates"), 
    TemplateVisualState(Name = "MouseOver", GroupName = "CommonStates"), 
    TemplateVisualState(Name = "Disabled", GroupName = "CommonStates"), 
    TemplateVisualState(Name = "Normal", GroupName = "CommonStates"), 
    TemplateVisualState(Name = "Focused", GroupName = "FocusStates"), 
    TemplateVisualState(Name = "Unfocused", GroupName = "FocusStates"), 
    TemplateVisualState(Name = "Valid", GroupName = "ValidationStatesStates"), 
    TemplateVisualState(Name = "InvalidUnfocused", GroupName = "ValidationStatesStates"), 
    TemplateVisualState(Name = "InvalidFocused", GroupName = "ValidationStatesStates"), 
    StyleTypedProperty(Property = "ValidationDecoratorStyle", StyleTargetType = typeof(ValidationDecorator)), 
    TemplatePart(Name = "Text", Type = typeof(TextBoxBase))]
    public class NumericBox : Control
    {
        // Fields
        private string _currencySymbol;
        private int _decimals;
        internal RepeatButton _elementDecrease;
        internal RepeatButton _elementIncrease;
        internal TextBoxBase _elementText;
        private string _format;
        private bool _isHex;
        private IList<string> _lastCorrectSymbols;
        private Key _lastInputKey;
        private string _numberDecimalSeparator;
        private string _numberGroupSeparator;
        private string _percentSymbol;
        private string _perMilleSymbol;
        private bool _retainDecimalSeparator;
        private bool _textTranslationNoMatterFocus;
        private int _textUpdateCounter;
        private bool _throwIsMouseOverChanged;
        private double _valueScale;
        public static readonly DependencyProperty AllowNullProperty = DependencyProperty.Register("AllowNull", typeof(bool), typeof(NumericBox), new PropertyMetadata(false));
        public static readonly DependencyProperty ButtonBackgroundProperty = DependencyProperty.Register("ButtonBackground", typeof(Brush), typeof(NumericBox), null);
        public static readonly DependencyProperty ButtonForegroundProperty = DependencyProperty.Register("ButtonForeground", typeof(Brush), typeof(NumericBox), null);
        public static readonly DependencyProperty CaretBrushProperty = DependencyProperty.Register("CaretBrush", typeof(Brush), typeof(NumericBox), null);
        public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(NumericBox), null);
        public static readonly DependencyProperty CultureProperty = DependencyProperty.Register("Culture", typeof(CultureInfo), typeof(NumericBox), new PropertyMetadata(CultureInfo.CurrentCulture, new PropertyChangedCallback(NumericBox.OnCulturePropertyChanged)));
        internal const string DecreaseElementName = "Decrease";
        public static readonly DependencyProperty DelayProperty = DependencyProperty.Register("Delay", typeof(int), typeof(NumericBox), new PropertyMetadata(300));
        public static readonly DependencyProperty DisabledCuesVisibilityProperty = DependencyProperty.Register("DisabledCuesVisibility", typeof(Visibility), typeof(NumericBox), new PropertyMetadata(Visibility.Visible));
        private static readonly Regex ExpFormatRegex = new Regex(@"^(e|E)(\+|\-)?0+");
        public static readonly DependencyProperty FocusBrushProperty = DependencyProperty.Register("FocusBrush", typeof(Brush), typeof(NumericBox), null);
        public static readonly DependencyProperty FocusCuesVisibilityProperty = DependencyProperty.Register("FocusCuesVisibility", typeof(Visibility), typeof(NumericBox), new PropertyMetadata(Visibility.Visible));
        internal static readonly DependencyProperty ForceMouseOverProperty = DependencyProperty.Register("ForceMouseOver", typeof(bool), typeof(NumericBox), new PropertyMetadata(new PropertyChangedCallback(NumericBox.OnForceMouseOverPropertyChanged)));
        public static readonly DependencyProperty FormatProperty = DependencyProperty.Register("Format", typeof(string), typeof(NumericBox), new PropertyMetadata("F0", new PropertyChangedCallback(NumericBox.OnFormatPropertyChanged)));
        public static readonly DependencyProperty HandleUpDownKeysProperty = DependencyProperty.Register("HandleUpDownKeys", typeof(bool), typeof(NumericBox), new PropertyMetadata(true));
        internal const string IncreaseElementName = "Increase";
        public static readonly DependencyProperty IncrementProperty = DependencyProperty.Register("Increment", typeof(double), typeof(NumericBox), new PropertyMetadata(1.0));
        public static readonly DependencyProperty IntervalProperty = DependencyProperty.Register("Interval", typeof(int), typeof(NumericBox), new PropertyMetadata(50, new PropertyChangedCallback(NumericBox.OnIntervalPropertyChanged)));
        public static readonly DependencyProperty IsFocusedProperty = DependencyProperty.Register("IsFocused", typeof(bool), typeof(NumericBox), new PropertyMetadata(new PropertyChangedCallback(NumericBox.OnIsFocusedPropertyChanged)));
        public static readonly DependencyProperty IsMouseOverProperty = DependencyProperty.Register("IsMouseOver", typeof(bool), typeof(NumericBox), new PropertyMetadata(new PropertyChangedCallback(NumericBox.OnIsMouseOverPropertyChanged)));
        public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(NumericBox), new PropertyMetadata(new PropertyChangedCallback(NumericBox.OnIsReadOnlyPropertyChanged)));
        public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register("Maximum", typeof(double), typeof(NumericBox), new PropertyMetadata((double)1.0 / (double)0.0, new PropertyChangedCallback(NumericBox.OnMaximumPropertyChanged)));
        public static readonly DependencyProperty MinimumProperty = DependencyProperty.Register("Minimum", typeof(double), typeof(NumericBox), new PropertyMetadata((double)-1.0 / (double)0.0, new PropertyChangedCallback(NumericBox.OnMinimumPropertyChanged)));
        public static readonly DependencyProperty MouseOverBrushProperty = DependencyProperty.Register("MouseOverBrush", typeof(Brush), typeof(NumericBox), null);
        public static readonly DependencyProperty PressedBrushProperty = DependencyProperty.Register("PressedBrush", typeof(Brush), typeof(NumericBox), null);
        public static readonly DependencyProperty RangeValidationModeProperty = DependencyProperty.Register("RangeValidationMode", typeof(RangeValidationMode), typeof(NumericBox), new PropertyMetadata(RangeValidationMode.OnLostFocus));
        public static readonly DependencyProperty SelectionBackgroundProperty = DependencyProperty.Register("SelectionBackground", typeof(Brush), typeof(NumericBox), null);
        public static readonly DependencyProperty SelectionForegroundProperty = DependencyProperty.Register("SelectionForeground", typeof(Brush), typeof(NumericBox), null);
        public static readonly DependencyProperty SelectionLengthProperty = DependencyProperty.Register("SelectionLength", typeof(int), typeof(NumericBox), new PropertyMetadata(0));
        public static readonly DependencyProperty SelectionStartProperty = DependencyProperty.Register("SelectionStart", typeof(int), typeof(NumericBox), new PropertyMetadata(0));
        public static readonly DependencyProperty SelectOnFocusProperty = DependencyProperty.Register("SelectOnFocus", typeof(SelectOnFocusCondition), typeof(NumericBox), new PropertyMetadata(SelectOnFocusCondition.OnDefaultSelection));
        public static readonly DependencyProperty ShowButtonsProperty = DependencyProperty.Register("ShowButtons", typeof(bool), typeof(NumericBox), new PropertyMetadata(true, new PropertyChangedCallback(NumericBox.OnShowButtonsPropertyChanged)));
        public static readonly DependencyProperty TextAlignmentProperty = DependencyProperty.Register("TextAlignment", typeof(TextAlignment), typeof(NumericBox), new PropertyMetadata(TextAlignment.Right));
        internal const string TextElementName = "Text";
        internal static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(NumericBox), null);
        public static readonly DependencyProperty ValidationDecoratorStyleProperty = DependencyProperty.Register("ValidationDecoratorStyle", typeof(Style), typeof(NumericBox), null);
        public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double), typeof(NumericBox), new PropertyMetadata(0.0, new PropertyChangedCallback(NumericBox.OnValuePropertyChanged)));
        public static readonly DependencyProperty WatermarkProperty = DependencyProperty.Register("Watermark", typeof(object), typeof(NumericBox), null);

        // Events
        public event EventHandler<PropertyChangedEventArgs<bool>> IsMouseOverChanged;
        public event EventHandler<PropertyChangedEventArgs<double>> ValueChanged;

        // Methods
        public NumericBox()
        {
            RoutedEventHandler handler = null;
            DependencyPropertyChangedEventHandler handler2 = null;
            this._format = string.Empty;
            this._valueScale = 1.0;
            this._lastCorrectSymbols = new List<string>();
            this._throwIsMouseOverChanged = true;
            base.DefaultStyleKey = typeof(NumericBox);
            if (handler == null)
            {
                handler = delegate(object param0, RoutedEventArgs param1)
                {
                    this.ChangeVisualStateButtonsVisibility(false);
                    this.ChangeVisualStateCommon(false);
                    this.ChangeVisualStateFocus(false);
                };
            }
            base.Loaded += handler;
            if (handler2 == null)
            {
                handler2 = (s, a) => this.ChangeVisualStateCommon(true);
            }
            base.IsEnabledChanged += handler2;
            base.GotFocus += new RoutedEventHandler(this.Control_GotFocus);
            base.LostFocus += new RoutedEventHandler(this.Control_LostFocus);
            base.MouseEnter += new MouseEventHandler(this.Control_MouseEnter);
            base.MouseLeave += new MouseEventHandler(this.Control_MouseLeave);
            this.SetCustomDefaultValues();
        }

        public bool BeginEdit(TextCompositionEventArgs inputEventArgs)
        {
            RoutedEventHandler handler = null;
            string keyChar = inputEventArgs.Text;
            if (handler == null)
            {
                handler = delegate(object s, RoutedEventArgs e)
                {
                    this.BeginInvoke(delegate
                    {
                        NumericBox box = this;
                        box._elementText.Text = keyChar;
                        box.Select(keyChar.Length, 0);
                    });
                };
            }
            base.GotFocus += handler;
            return true;
        }

        private void Control_GotFocus(object sender, RoutedEventArgs e)
        {
            this.IsFocused = true;
        }

        private void Control_LostFocus(object sender, RoutedEventArgs e)
        {
            this.IsFocused = false;
        }

        private void Control_MouseEnter(object sender, MouseEventArgs e)
        {
            if (InputEventArgs.GetPointerType(e) == PointerDeviceType.Mouse)
            {
                this.IsMouseOver = true;
            }
        }

        private void Control_MouseLeave(object sender, MouseEventArgs e)
        {
            if (InputEventArgs.GetPointerType(e) == PointerDeviceType.Mouse)
            {
                this.IsMouseOver = false;
            }
        }

        private void NumericBox_GotFocus(object sender, RoutedEventArgs e)
        {
            this.IsFocused = true;
        }

        private void NumericBox_LostFocus(object sender, RoutedEventArgs e)
        {
            this.IsFocused = false;
        }

        private void NumericBox_MouseEnter(object sender, MouseEventArgs e)
        {
            this.IsMouseOver = true;
        }

        private void NumericBox_MouseLeave(object sender, MouseEventArgs e)
        {
            this.IsMouseOver = false;
        }

        private void CalculateDigits(string str, bool skipLeadingZeros, int stopAtDigitCount, out int digitCount, out int digitIdx)
        {
            digitCount = 0;
            digitIdx = -1;
            if (!string.IsNullOrEmpty(str))
            {
                int num = 0;
                if (skipLeadingZeros)
                {
                    num = this.SkipLeadingZeros(str);
                }
                while (num < str.Length)
                {
                    if (char.IsDigit(str[num]))
                    {
                        digitCount++;
                        digitIdx = num;
                        if ((stopAtDigitCount > 0) && (digitCount == stopAtDigitCount))
                        {
                            return;
                        }
                    }
                    num++;
                }
            }
        }

        protected void ChangeVisualStateButtonsVisibility(bool useTransitions)
        {
            if (!this.ShowButtons)
            {
                VisualStateHelper.GoToState(this, "HideButtons", useTransitions);
            }
            if (this.ShowButtons)
            {
                VisualStateHelper.GoToState(this, "ShowButtons", useTransitions);
            }
        }

        protected void ChangeVisualStateCommon(bool useTransitions)
        {
            if (!base.IsEnabled)
            {
                VisualStateHelper.GoToState(this, "Disabled", useTransitions);
            }
            if (base.IsEnabled)
            {
                VisualStateHelper.GoToState(this, "MouseOver", useTransitions);
            }
            if ((base.IsEnabled && !this.IsMouseOver) && !this.ForceMouseOver)
            {
                VisualStateHelper.GoToState(this, "Normal", useTransitions);
            }
        }

        protected void ChangeVisualStateFocus(bool useTransitions)
        {
            if (!this.IsFocused)
            {
                VisualStateHelper.GoToState(this, "Unfocused", useTransitions);
            }
            if (this.IsFocused)
            {
                VisualStateHelper.GoToState(this, "Focused", useTransitions);
            }
        }

        private string ConvertToInvariantNumber(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return str;
            }
            StringBuilder builder = new StringBuilder(str.Length);
            foreach (char ch in str)
            {
                builder.Append((char.IsDigit(ch) && (ch > '9')) ? ((char)(0x30 + ((int)char.GetNumericValue(ch)))) : ch);
            }
            return builder.ToString();
        }

        private string CutDecimals(string value)
        {
            if (string.IsNullOrEmpty(value) || (this._decimals < 0))
            {
                return value;
            }
            value = value.Trim();
            int index = value.IndexOf(this._numberDecimalSeparator);
            if (index < 0)
            {
                return value;
            }
            StringBuilder builder = new StringBuilder(value.Length);
            builder.Append(value.Substring(0, index));
            int num2 = this._decimals;
            int num3 = 0;
            for (int i = index + this._numberDecimalSeparator.Length; i < value.Length; i++)
            {
                char c = value[i];
                if (char.IsDigit(c))
                {
                    num3++;
                    if (num3 <= num2)
                    {
                        if (num3 == 1)
                        {
                            builder.Append(this._numberDecimalSeparator);
                        }
                        builder.Append(c);
                    }
                }
                else
                {
                    builder.Append(value.Substring(i));
                    break;
                }
            }
            return builder.ToString();
        }

        internal void ElementDecrease_Click(object sender, RoutedEventArgs e)
        {
            base.Focus();
            if (double.IsNaN(this.Value))
            {
                this.SetValue(this.DefaultValue, true);
            }
            else
            {
                this.SetValue(this.Value - (this.Increment / this._valueScale), true);
            }
            this.SelectDefaultText();
        }

        internal void ElementIncrease_Click(object sender, RoutedEventArgs e)
        {
            base.Focus();
            if (double.IsNaN(this.Value))
            {
                this.SetValue(this.DefaultValue, true);
            }
            else
            {
                this.SetValue(this.Value + (this.Increment / this._valueScale), true);
            }
            this.SelectDefaultText();
        }

        private void ElementText_GotFocus(object sender, RoutedEventArgs e)
        {
            this.UpdateTextFromValue();
            if ((this.SelectOnFocus == SelectOnFocusCondition.Always) || (((this.SelectOnFocus == SelectOnFocusCondition.OnDefaultSelection) && (this.SelectionStart == 0)) && (this.SelectionLength == 0)))
            {
                this.SelectDefaultText();
            }
        }

        private void ElementText_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (this.IsReadOnly)
            {
                e.Handled = true;
            }
            else
            {
                this._lastInputKey = e.Key;
                e.Handled = this.ProcessInputKey(e.Key);
            }
        }

        private void ElementText_LostFocus(object sender, RoutedEventArgs e)
        {
            this._textTranslationNoMatterFocus = true;
            try
            {
                this.ElementText_TextTranslation(this._elementText, EventArgs.Empty);
            }
            finally
            {
                this._textTranslationNoMatterFocus = false;
            }
            this.SetValue(this.Value, true);
            this.UpdateTextFromValue();
        }

        private void ElementText_SelectionChanged(object sender, RoutedEventArgs e)
        {
            this.SelectionStart = this._elementText.SelectionStart;
            this.SelectionLength = this._elementText.SelectionLength;
        }

        private void ElementText_TextTranslation(object sender, EventArgs e)
        {
            Key lastKey = this._lastInputKey;
            this._lastInputKey = Key.None;
            if (!this.IsTextUpdateSuspended && (this._textTranslationNoMatterFocus || (this.GetLogicalFocusedElement() == this._elementText)))
            {
                string text = this._elementText.Text;
                if (Regex.IsMatch(text, @"^-0*(\.|\" + this._numberDecimalSeparator + ")?0*$"))
                {
                    this._lastCorrectSymbols = CompositeTextUtils.ConvertToSymbolList(text);
                }
                else
                {
                    string newText = CompositeTextUtils.ConvertSymbolListToString(this._lastCorrectSymbols);
                    bool flag = this._format == "";
                    IList<string> newTextArr = CompositeTextUtils.ConvertToSymbolList(text);
                    TextChangeInfo info = CompositeTextUtils.GetTextChange(this._lastCorrectSymbols, newTextArr, this._elementText.SelectionStart);
                    this._retainDecimalSeparator = flag;
                    bool checkRange = this.RangeValidationMode != RangeValidationMode.OnLostFocus;
                    try
                    {
                        string[] strArray = null;
                        if (((!flag && (info.AddedLength == 0)) && ((info.RemovedLength == 1) && (this._lastCorrectSymbols[info.Offset] == this._numberDecimalSeparator))) && ((lastKey == Key.Delete) || (lastKey == Key.Back)))
                        {
                            this.UpdateTextFromValue();
                            this.Select(this.Text.IndexOf(this._numberDecimalSeparator) + ((lastKey == Key.Back) ? 0 : 1), 0);
                        }
                        else if (this.IsDecimalSeparatorTyped(text, lastKey))
                        {
                            if (this.Value == 0.0)
                            {
                                this.UpdateTextFromValue();
                            }
                            else
                            {
                                this.SetValue(0.0, checkRange);
                            }
                            int index = this._elementText.Text.IndexOf(this._numberDecimalSeparator);
                            if (index >= 0)
                            {
                                index++;
                            }
                            else
                            {
                                index = this._elementText.Text.IndexOfAny(new char[] { 'E', 'e' });
                                if (index < 0)
                                {
                                    index = this._elementText.Text.Length;
                                }
                            }
                            this.Select(index, 0);
                        }
                        else
                        {
                            double defaultValue;
                            if (info.AddedLength == 1)
                            {
                                string symbol = newTextArr[info.Offset];
                                if (this.IsDecimalSeparatorTyped(symbol, lastKey))
                                {
                                    strArray = new string[] { this._numberDecimalSeparator };
                                }
                                else if (!this._isHex && ((symbol.ToLower() == "e") || (lastKey == Key.E)))
                                {
                                    strArray = new string[] { "E", "e" };
                                }
                                if (strArray != null)
                                {
                                    if ((flag && (strArray[0] == this._numberDecimalSeparator)) && (!this._lastCorrectSymbols.Contains(strArray[0]) && (symbol == ".")))
                                    {
                                        text = text.Replace(".", this._numberDecimalSeparator);
                                    }
                                    this.UpdateTextFromValue();
                                    foreach (string str4 in strArray)
                                    {
                                        int num3 = this._lastCorrectSymbols.IndexOf(str4);
                                        if (num3 >= 0)
                                        {
                                            this.Select(num3 + 1, 0);
                                            break;
                                        }
                                    }
                                    if (flag)
                                    {
                                        if (text == this._numberDecimalSeparator)
                                        {
                                            text = newText + this._numberDecimalSeparator;
                                        }
                                    }
                                    else
                                    {
                                        return;
                                    }
                                }
                            }
                            if ((!flag || (text.IndexOfAny(new char[] { 'e', 'E' }) < 0)) && this.TryParseValue(text, out defaultValue))
                            {
                                if (double.IsNaN(defaultValue) && !this.AllowNull)
                                {
                                    defaultValue = this.DefaultValue;
                                }
                                if (defaultValue != this.Value)
                                {
                                    string originalText = text;
                                    int selectionStart = this._elementText.SelectionStart;
                                    this.SetValue(defaultValue, checkRange);
                                    if (!checkRange || this.IsInRange(defaultValue))
                                    {
                                        int num5;
                                        if ((flag && (strArray != null)) && (strArray[0] == this._numberDecimalSeparator))
                                        {
                                            num5 = this._elementText.Text.IndexOf(this._numberDecimalSeparator) + 1;
                                        }
                                        else
                                        {
                                            num5 = this.GetTranslatedCursorPosition(originalText, this._elementText.Text, selectionStart);
                                        }
                                        this.Select(num5, 0);
                                    }
                                }
                                else if (flag)
                                {
                                    this.UpdateText(this.NormalizeEmptyFormatText(text));
                                }
                                else
                                {
                                    int start = this._elementText.SelectionStart;
                                    this.UpdateTextFromValue();
                                    this.Select(start, 0);
                                }
                            }
                            else if (flag)
                            {
                                this.UpdateText(newText);
                                this.UpdateSelection();
                            }
                            else
                            {
                                this.UpdateTextFromValue();
                            }
                        }
                    }
                    finally
                    {
                        this._retainDecimalSeparator = false;
                    }
                }
            }
        }

        private int GetCursorPositionWithoutSymbols(string text, int position)
        {
            int num = 0;
            for (int i = 0; i < position; i++)
            {
                if ((char.IsDigit(text[i]) || (text[i] == '-')) || (text[i] == this._numberDecimalSeparator[0]))
                {
                    num++;
                }
            }
            return num;
        }

        private int GetDecimalSeparatorPosition(out bool afterDecimalSeparator)
        {
            string text = this._elementText.Text;
            afterDecimalSeparator = (text.IndexOf(this._numberDecimalSeparator) + 1) == this.SelectionStart;
            return this.GetCursorPositionWithoutSymbols(text, text.IndexOf(this._numberDecimalSeparator));
        }

        private T GetTemplateChild<T>(string childName, bool required, ref string errors) where T : class
        {
            DependencyObject templateChild = base.GetTemplateChild(childName);
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "template part", childName, templateChild, required, ref errors);
            return (templateChild as T);
        }

        private static Storyboard GetTemplateChildResource(FrameworkElement root, string resourceName, bool required, ref string errors)
        {
            return GetTemplateChildResource<Storyboard>(root, resourceName, required, ref errors);
        }

        private static T GetTemplateChildResource<T>(FrameworkElement root, string resourceName, bool required, ref string errors) where T : class
        {
            object child = root.Resources[resourceName];
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "resource", resourceName, child, required, ref errors);
            return (child as T);
        }

        private string GetTextValue()
        {
            return this._elementText.Text;
        }

        private int GetTranslatedCursorPosition(string originalText, string translatedText, int originalPosition)
        {
            if ((string.IsNullOrEmpty(originalText) || string.IsNullOrEmpty(translatedText)) || (originalPosition == 0))
            {
                return originalPosition;
            }
            int num = originalPosition;
            int index = translatedText.ToUpper().IndexOf("E");
            if ((originalText.ToUpper().IndexOf("E") >= 0) != (index >= 0))
            {
                return originalPosition;
            }
            originalText = originalText.Trim();
            translatedText = translatedText.Trim();
            bool flag = originalPosition == originalText.Length;
            int length = Math.Min(originalPosition + 1, originalText.Length);
            originalText = originalText.Substring(0, length);
            char ch = originalText[length - 1];
            if (originalText.ToUpper().IndexOf("E") < 0)
            {
                int num5;
                int num6;
                int num7;
                if (IsSign(ch))
                {
                    if (!IsSign(translatedText[0]))
                    {
                        return 0;
                    }
                    return 1;
                }
                this.CalculateDigits(originalText, true, -1, out num5, out num6);
                if (num5 <= 0)
                {
                    return num;
                }
                this.CalculateDigits(translatedText, true, num5, out num7, out num6);
                if (num6 < 0)
                {
                    return num;
                }
                num = num6;
                if ((!flag && char.IsDigit(ch)) && (num7 >= num5))
                {
                    return num;
                }
                num++;
            }
            return num;
        }

        private void HandleIsReadOnlyProperty()
        {
            if (this._elementDecrease != null)
            {
                this._elementDecrease.IsEnabled = !this.IsReadOnly;
            }
            if (this._elementIncrease != null)
            {
                this._elementIncrease.IsEnabled = !this.IsReadOnly;
            }
            if (this._elementText != null)
            {
                this._elementText.IsReadOnly = this.IsReadOnly;
            }
        }

        private void InitializeDecreasePart()
        {
            this._elementDecrease.Click += new RoutedEventHandler(this.ElementDecrease_Click);
        }

        private void InitializeIncreasePart()
        {
            this._elementIncrease.Click += new RoutedEventHandler(this.ElementIncrease_Click);
        }

        private void InitializeTextPart()
        {
            this._elementText.FlowDirection = FlowDirection.LeftToRight;
            base.GotFocus += new RoutedEventHandler(this.NumericBox_GotFocus);
            base.LostFocus += new RoutedEventHandler(this.NumericBox_LostFocus);
            base.MouseEnter += new MouseEventHandler(this.NumericBox_MouseEnter);
            base.MouseLeave += new MouseEventHandler(this.NumericBox_MouseLeave);
            this._elementText.GotFocus += new RoutedEventHandler(this.ElementText_GotFocus);
            this._elementText.LostFocus += new RoutedEventHandler(this.ElementText_LostFocus);
            this._elementText.TextTranslation += new EventHandler(this.ElementText_TextTranslation);
            this._elementText.SelectOnFocus = SelectOnFocusCondition.Never;
            this._elementText.KeyDown += new KeyEventHandler(this.ElementText_KeyDown);
            this._elementText.BindInputMethodProperties(this);
            this.UpdateTextFromValue();
            this.UpdateSelection();
            this._elementText.SelectionChanged += new RoutedEventHandler(this.ElementText_SelectionChanged);
        }

        private bool IsDecimalSeparatorTyped(string symbol, Key lastKey)
        {
            return (((lastKey == Key.Decimal) && (symbol == ".")) || (symbol == this._numberDecimalSeparator));
        }

        private bool IsInRange(double value)
        {
            return ((this.AllowNull && double.IsNaN(value)) || ((value >= this.Minimum) && (value <= this.Maximum)));
        }

        private static bool IsSign(char ch)
        {
            if (ch != '+')
            {
                return (ch == '-');
            }
            return true;
        }

        private string NormalizeEmptyFormatText(string strVal)
        {
            if (string.IsNullOrEmpty(strVal))
            {
                return strVal;
            }
            strVal = strVal.Trim();
            StringBuilder builder = new StringBuilder(strVal.Length);
            bool flag = false;
            bool flag2 = true;
            for (int i = 0; (i < strVal.Length) && flag2; i++)
            {
                char ch = strVal[i];
                if ((i == 0) && (ch == '-'))
                {
                    flag2 = true;
                    builder.Append(ch);
                }
                else if (char.IsDigit(ch))
                {
                    flag2 = char.GetNumericValue(ch) == 0.0;
                    if (flag2 && !flag)
                    {
                        builder.Append(ch);
                        flag = true;
                    }
                }
                else
                {
                    flag2 = ch != this._numberDecimalSeparator[0];
                }
                if (!flag2)
                {
                    builder.Append(strVal.Substring(i));
                }
            }
            return builder.ToString();
        }

        private void OnAfterApplyTemplate()
        {
            this.HandleIsReadOnlyProperty();
        }

        public override void OnApplyTemplate()
        {
            string errors = string.Empty;
            base.OnApplyTemplate();
            this._elementText = this.GetTemplateChild<TextBoxBase>("Text", true, ref errors);
            if (this._elementText != null)
            {
                this.InitializeTextPart();
            }
            this._elementIncrease = this.GetTemplateChild<RepeatButton>("Increase", false, ref errors);
            if (this._elementIncrease != null)
            {
                this.InitializeIncreasePart();
            }
            this._elementDecrease = this.GetTemplateChild<RepeatButton>("Decrease", false, ref errors);
            if (this._elementDecrease != null)
            {
                this.InitializeDecreasePart();
            }
            if (!string.IsNullOrEmpty(errors))
            {
                if ((base.Template != null) && !PlatformIndependent.IsInDesignMode(this))
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Template cannot be applied to NumericBox.\nDetails: {0}", new object[] { errors }));
                }
            }
            else
            {
                this.ChangeVisualStateButtonsVisibility(false);
                this.ChangeVisualStateCommon(false);
                this.ChangeVisualStateFocus(false);
                this.OnAfterApplyTemplate();
            }
        }

        private void OnCultureChanged(CultureInfo oldValue)
        {
            if (this.Culture == null)
            {
                this.Culture = oldValue;
            }
            else
            {
                NumberFormatInfo numberFormat = this.Culture.NumberFormat;
                this._numberGroupSeparator = numberFormat.NumberGroupSeparator;
                this._numberDecimalSeparator = numberFormat.NumberDecimalSeparator;
                this._percentSymbol = numberFormat.PercentSymbol;
                this._perMilleSymbol = numberFormat.PerMilleSymbol;
                this._currencySymbol = numberFormat.CurrencySymbol;
                if (this.Format != null)
                {
                    this.UpdateFormat(this.Format);
                }
            }
        }

        private static void OnCulturePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            NumericBox box = d as NumericBox;
            CultureInfo oldValue = (CultureInfo)e.OldValue;
            box.OnCultureChanged(oldValue);
        }

        private static void OnForceMouseOverPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as NumericBox).ChangeVisualStateCommon(true);
        }

        private void OnFormatChanged(string oldValue)
        {
            if (!this.UpdateFormat(this.Format))
            {
                string format = this.Format;
                this.Format = oldValue;
                throw new ArgumentException(string.Format("Invalid format {0}", format));
            }
        }

        private static void OnFormatPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            NumericBox box = d as NumericBox;
            string oldValue = (string)e.OldValue;
            box.OnFormatChanged(oldValue);
        }

        private void OnIntervalChanged(int oldValue)
        {
        }

        private static void OnIntervalPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            NumericBox box = d as NumericBox;
            int oldValue = (int)e.OldValue;
            box.OnIntervalChanged(oldValue);
        }

        private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as NumericBox).ChangeVisualStateFocus(true);
        }

        private static void OnIsMouseOverPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            NumericBox sender = d as NumericBox;
            if ((sender.IsMouseOverChanged != null) && sender._throwIsMouseOverChanged)
            {
                PropertyChangedEventArgs<bool> args = new PropertyChangedEventArgs<bool>
                {
                    OldValue = (bool)e.OldValue,
                    NewValue = (bool)e.NewValue
                };
                sender.IsMouseOverChanged(sender, args);
            }
            sender.ChangeVisualStateCommon(true);
        }

        private void OnIsReadOnlyChanged(bool oldValue)
        {
            this.HandleIsReadOnlyProperty();
        }

        private static void OnIsReadOnlyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            NumericBox box = d as NumericBox;
            bool oldValue = (bool)e.OldValue;
            box.OnIsReadOnlyChanged(oldValue);
        }

        internal bool OnKeyDown(Key key, int platformKeyCode, string keyString, bool ctrlPressed)
        {
            return false;
        }

        private void OnMaximumChanged(double oldValue)
        {
            if (this.Maximum < this.Minimum)
            {
                this.Maximum = this.Minimum;
            }
            else if ((this.RangeValidationMode != RangeValidationMode.OnLostFocus) && !this.IsInRange(this.Value))
            {
                this.Value = this.Maximum;
            }
        }

        private static void OnMaximumPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            NumericBox box = d as NumericBox;
            double oldValue = (double)e.OldValue;
            box.OnMaximumChanged(oldValue);
        }

        private void OnMinimumChanged(double oldValue)
        {
            if (this.Minimum > this.Maximum)
            {
                this.Minimum = this.Maximum;
            }
            else if ((this.RangeValidationMode != RangeValidationMode.OnLostFocus) && !this.IsInRange(this.Value))
            {
                this.Value = this.Minimum;
            }
        }

        private static void OnMinimumPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            NumericBox box = d as NumericBox;
            double oldValue = (double)e.OldValue;
            box.OnMinimumChanged(oldValue);
        }

        private static void OnShowButtonsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as NumericBox).ChangeVisualStateButtonsVisibility(true);
        }

        protected virtual void OnValueChanged(PropertyChangedEventArgs<double> e)
        {
            if (this.ValueChanged != null)
            {
                this.ValueChanged(this, e);
            }
        }

        private void OnValueChanged(double oldValue)
        {
            double d = this.Value;
            if (!this.AllowOutOfRangeValues)
            {
                if (double.IsNaN(d))
                {
                    if (!this.AllowNull)
                    {
                        d = this.DefaultValue;
                    }
                }
                else if (this.RangeValidationMode == RangeValidationMode.Always)
                {
                    if (!this.IsInRange(d))
                    {
                        d = oldValue;
                    }
                }
                else
                {
                    if (d < this.Minimum)
                    {
                        d = this.Minimum;
                    }
                    if (d > this.Maximum)
                    {
                        d = this.Maximum;
                    }
                }
            }
            if ((!double.IsNaN(d) || !double.IsNaN(this.Value)) && (d != this.Value))
            {
                base.SetValue(ValueProperty, d);
            }
            else
            {
                this.UpdateTextFromValue();
                PropertyChangedEventArgs<double> e = new PropertyChangedEventArgs<double>
                {
                    OldValue = oldValue,
                    NewValue = this.Value
                };
                this.OnValueChanged(e);
            }
        }

        private static void OnValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            NumericBox box = d as NumericBox;
            double oldValue = (double)e.OldValue;
            box.OnValueChanged(oldValue);
        }

        private string PrepareForParsing(string value)
        {
            if (!string.IsNullOrEmpty(value))
            {
                value = value.Replace(this._percentSymbol, "").Replace(this._perMilleSymbol, "").Replace(this._currencySymbol, "").Replace(this._numberGroupSeparator, "").Replace(".", this._numberDecimalSeparator);
                value = this.ConvertToInvariantNumber(value);
                if (value.StartsWith("-" + this._numberDecimalSeparator))
                {
                    value = value.Insert(1, "0");
                }
            }
            return value;
        }

        private bool ProcessInputKey(Key key)
        {
            if (((key != Key.Up) && (key != Key.Down)) && ((key != Key.PageUp) && (key != Key.PageDown)))
            {
                return false;
            }
            if (!this.HandleUpDownKeys)
            {
                return false;
            }
            if (this.Increment != 0.0)
            {
                double increment = 0.0;
                switch (key)
                {
                    case Key.PageUp:
                        increment = this.Increment * 10.0;
                        break;

                    case Key.PageDown:
                        increment = -this.Increment * 10.0;
                        break;

                    case Key.Up:
                        increment = this.Increment;
                        break;

                    case Key.Down:
                        increment = -this.Increment;
                        break;
                }
                if (increment != 0.0)
                {
                    increment /= this._valueScale;
                    if (double.IsNaN(this.Value))
                    {
                        this.SetValue(this.DefaultValue, true);
                    }
                    else
                    {
                        this.SetValue(this.Value + increment, true);
                    }
                    this.SelectDefaultText();
                }
            }
            return true;
        }

        private void ResumeTextUpdate()
        {
            base.Dispatcher.BeginInvoke(new Action(this.ResumeTextUpdateImpl));
        }

        private void ResumeTextUpdateImpl()
        {
            if (this._textUpdateCounter > 0)
            {
                this._textUpdateCounter--;
            }
            if (((this._textUpdateCounter == 0) && (this._elementText != null)) && (CompositeTextUtils.ConvertSymbolListToString(this._lastCorrectSymbols) != this._elementText.Text))
            {
                this.ElementText_TextTranslation(this._elementText, EventArgs.Empty);
            }
        }

        public void Select(int start, int length)
        {
            this.SelectionStart = start;
            this.SelectionLength = length;
            this.UpdateSelection();
        }

        internal void SelectDefaultText()
        {
            this.SelectionStart = 0;
            this.SelectionLength = this._elementText.Text.Length;
            this.UpdateSelection();
        }

        private void SetCursorPosition(int position, bool beforeThousandSeparator)
        {
            int num = 0;
            string text = this._elementText.Text;
            if (!string.IsNullOrEmpty(text))
            {
                text = text.TrimEnd(new char[] { this._percentSymbol[0] });
            }
            this._elementText.SelectionLength = 0;
            for (int i = 0; i < text.Length; i++)
            {
                if ((char.IsDigit(text[i]) || (text[i] == '-')) || (text[i] == this._numberDecimalSeparator[0]))
                {
                    num++;
                    if (num > position)
                    {
                        this._elementText.SelectionStart = i;
                        return;
                    }
                }
                if (((num == position) && beforeThousandSeparator) && (text[i] == this._numberGroupSeparator[0]))
                {
                    this._elementText.SelectionStart = i;
                    return;
                }
            }
            this._elementText.SelectionStart = text.Length;
        }

        private void SetCustomDefaultValues()
        {
            base.IsTabStop = false;
            this.UpdateFormat(this.Format);
            this.OnCultureChanged(this.Culture);
        }

        public void SetValue(double value, bool checkRange)
        {
            if (checkRange && !this.IsInRange(value))
            {
                double oldValue = this.Value;
                this.Value = value;
                if (this.Value == oldValue)
                {
                    this.OnValueChanged(oldValue);
                }
            }
            else
            {
                this.AllowOutOfRangeValues = true;
                this.Value = value;
                this.AllowOutOfRangeValues = false;
            }
        }

        private int SkipLeadingZeros(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return 0;
            }
            for (int i = 0; i < str.Length; i++)
            {
                if (SubstrEqual(this._numberDecimalSeparator, str, i) || SubstrEqual(".", str, i))
                {
                    return i;
                }
                char c = str[i];
                if (char.IsDigit(c) && (char.GetNumericValue(c) != 0.0))
                {
                    return i;
                }
            }
            return str.Length;
        }

        private static bool SubstrEqual(string substr, string str, int idx)
        {
            return (string.Compare(substr, 0, str, idx, (substr != null) ? substr.Length : 0) == 0);
        }

        private void SuspendTextUpdate()
        {
            this._textUpdateCounter++;
        }

        private bool TryParseValue(string value, out double result)
        {
            bool flag;
            result = 0.0;
            value = this.PrepareForParsing(value);
            if (string.IsNullOrEmpty(value))
            {
                flag = true;
                result = double.NaN;
            }
            else if (this._isHex)
            {
                int num;
                flag = int.TryParse(value, NumberStyles.HexNumber, this.Culture.NumberFormat, out num);
                if (flag)
                {
                    result = num;
                }
            }
            else if (value == this._numberDecimalSeparator)
            {
                flag = true;
                result = 0.0;
            }
            else
            {
                flag = double.TryParse(value, NumberStyles.Any, (IFormatProvider)this.Culture.NumberFormat, out result);
                if (flag)
                {
                    string s = this.CutDecimals(value);
                    if (value == "")
                    {
                        result = 0.0;
                    }
                    else
                    {
                        double num2;
                        if (double.TryParse(s, NumberStyles.Any, (IFormatProvider)this.Culture.NumberFormat, out num2))
                        {
                            result = num2;
                        }
                    }
                }
            }
            if (flag)
            {
                result /= this._valueScale;
            }
            return flag;
        }

        private bool UpdateFormat(string format)
        {
            this._format = "0";
            this._isHex = false;
            int count = 0;
            int num2 = 0;
            int repeatCount = 0;
            if (format.Length == 0)
            {
                this._decimals = -1;
                this._format = string.Empty;
            }
            else if (!Regex.IsMatch(format, @"^(F|N|C|P|D|E|G|R|X)\d?$", RegexOptions.IgnoreCase))
            {
                int length;
                this._decimals = 0;
                bool flag = false;
                string str = null;
                bool flag2 = false;
                bool flag3 = false;
                bool flag4 = false;
                bool flag5 = false;
                int num4 = 0;
                for (int i = 0; i < format.Length; i += length)
                {
                    length = 1;
                    if (flag2)
                    {
                        flag2 = false;
                    }
                    else
                    {
                        char ch2 = format[i];
                        if (ch2 == ';')
                        {
                            break;
                        }
                        char ch4 = ch2;
                        if (ch4 <= 'E')
                        {
                            switch (ch4)
                            {
                                case '#':
                                case '0':
                                    goto Label_0231;

                                case '%':
                                    count++;
                                    break;

                                case ',':
                                    num4++;
                                    break;

                                case '.':
                                    if (!flag3 && !flag4)
                                    {
                                        repeatCount = num4;
                                        flag3 = true;
                                    }
                                    break;

                                case 'E':
                                    goto Label_0286;
                            }
                        }
                        else if (ch4 == '\\')
                        {
                            flag2 = true;
                        }
                        else
                        {
                            if (ch4 == 'e')
                            {
                                goto Label_0286;
                            }
                            if (ch4 == '‰')
                            {
                                goto Label_0280;
                            }
                        }
                    }
                    continue;
                Label_0231:
                    if (!flag4)
                    {
                        if (flag3)
                        {
                            this._decimals++;
                        }
                        else if (flag5)
                        {
                            if (num4 > 0)
                            {
                                flag = true;
                                num4 = 0;
                            }
                        }
                        else
                        {
                            flag5 = true;
                        }
                    }
                    continue;
                Label_0280:
                    num2++;
                    continue;
                Label_0286:
                    if (!flag4)
                    {
                        Match match = ExpFormatRegex.Match(format.Substring(i));
                        if (match.Success)
                        {
                            if (!flag3)
                            {
                                repeatCount = num4;
                            }
                            str = match.Value;
                            length = str.Length;
                            flag4 = true;
                        }
                    }
                }
                bool flag6 = this._decimals == 0;
                flag = flag && (str == null);
                StringBuilder builder = new StringBuilder((flag6 && !flag) ? "0" : "#");
                if (flag)
                {
                    builder.Append(flag6 ? ",0" : ",#");
                }
                if (repeatCount > 0)
                {
                    builder.Append(',', repeatCount);
                }
                if (!flag6)
                {
                    builder.Append('.');
                    builder.Append('0', this._decimals);
                }
                if (str != null)
                {
                    builder.Append(str);
                }
                if (count > 0)
                {
                    builder.Insert(builder.Length, this._percentSymbol, count);
                }
                if (num2 > 0)
                {
                    builder.Insert(builder.Length, this._perMilleSymbol, num2);
                }
                this._format = builder.ToString();
            }
            else
            {
                char ch = char.ToUpper(format[0]);
                switch (ch)
                {
                    case 'C':
                        this._decimals = this.Culture.NumberFormat.CurrencyDecimalDigits;
                        break;

                    case 'E':
                        this._decimals = 6;
                        break;

                    case 'G':
                    case 'R':
                        this._decimals = -1;
                        format = string.Empty;
                        break;

                    case 'P':
                        this._decimals = this.Culture.NumberFormat.PercentDecimalDigits;
                        count = 1;
                        break;

                    default:
                        this._decimals = this.Culture.NumberFormat.NumberDecimalDigits;
                        break;
                }
                if ((format.Length > 1) && char.IsDigit(format[1]))
                {
                    try
                    {
                        this._decimals = int.Parse(format.Substring(1));
                    }
                    catch
                    {
                    }
                }
                if (ch == 'E')
                {
                    format = ((this._decimals > 0) ? ("#." + new string('0', this._decimals)) : "0") + format[0] + "0";
                }
                this._isHex = ch == 'X';
                this._format = format;
            }
            int num7 = (count * 2) + ((num2 - repeatCount) * 3);
            this._valueScale = (num7 == 0) ? 1.0 : Math.Pow(10.0, (double)num7);
            this.UpdateTextFromValue();
            return true;
        }

        private void UpdateSelection()
        {
            if ((this._elementText != null) && ((this._elementText.SelectionStart != this.SelectionStart) || (this._elementText.SelectionLength != this.SelectionLength)))
            {
                this._elementText.Select(this.SelectionStart, this.SelectionLength);
            }
        }

        private void UpdateText(string newText)
        {
            if (this._elementText != null)
            {
                this.SuspendTextUpdate();
                try
                {
                    this._elementText.Text = newText;
                    this._lastCorrectSymbols = CompositeTextUtils.ConvertToSymbolList(newText);
                }
                finally
                {
                    this.ResumeTextUpdate();
                }
            }
        }

        private void UpdateTextFromValue()
        {
            this.SuspendTextUpdate();
            try
            {
                if (this._elementText != null)
                {
                    string str2;
                    bool flag = (this.GetLogicalFocusedElement() == this._elementText) && !this.IsReadOnly;
                    bool flag2 = this._retainDecimalSeparator && flag;
                    string format = flag ? this._format : this.Format;
                    if (double.IsNaN(this.Value))
                    {
                        str2 = "";
                    }
                    else
                    {
                        str2 = this._isHex ? ((int)this.Value).ToString(format, this.Culture.NumberFormat) : this.Value.ToString(format, this.Culture.NumberFormat);
                    }
                    if (flag)
                    {
                        if (((!flag2 && (str2.Length > 1)) && (char.IsDigit(str2[0]) && (char.GetNumericValue(str2[0]) == 0.0))) && (str2[1] == this._numberDecimalSeparator[0]))
                        {
                            str2 = str2.Substring(1);
                        }
                        if ((flag2 && (this._elementText.Text.Contains(this._numberDecimalSeparator) || this._elementText.Text.Contains("."))) && !str2.Contains(this._numberDecimalSeparator))
                        {
                            str2 = str2 + this._numberDecimalSeparator;
                        }
                        this._lastCorrectSymbols = CompositeTextUtils.ConvertToSymbolList(str2);
                    }
                    this._elementText.Text = str2;
                    this.UpdateSelection();
                }
            }
            finally
            {
                this.ResumeTextUpdate();
            }
        }

        // Properties
        public bool AllowNull
        {
            get { return (bool)GetValue(AllowNullProperty); }
            set { SetValue(AllowNullProperty, value); }
        }

        private bool AllowOutOfRangeValues { get; set; }

        public Brush ButtonBackground
        {
            get { return (Brush)GetValue(ButtonBackgroundProperty); }
            set { SetValue(ButtonBackgroundProperty, value); }
        }

        public Brush ButtonForeground
        {
            get { return (Brush)GetValue(ButtonForegroundProperty); }
            set { SetValue(ButtonForegroundProperty, value); }
        }

        public Brush CaretBrush
        {
            get { return (Brush)GetValue(CaretBrushProperty); }
            set { SetValue(CaretBrushProperty, value); }
        }

        public CornerRadius CornerRadius
        {
            get { return (CornerRadius)GetValue(CornerRadiusProperty); }
            set { SetValue(CornerRadiusProperty, value); }
        }

        public CultureInfo Culture
        {
            get { return (CultureInfo)GetValue(CultureProperty); }
            set { SetValue(CultureProperty, value); }
        }

        private double DefaultValue
        {
            get
            {
                if (this.Minimum > 0.0)
                {
                    return this.Minimum;
                }
                if (this.Maximum >= 0.0)
                {
                    return 0.0;
                }
                return this.Maximum;
            }
        }

        public int Delay
        {
            get { return (int)GetValue(DelayProperty); }
            set { SetValue(DelayProperty, value); }
        }

        public Visibility DisabledCuesVisibility
        {
            get { return (Visibility)GetValue(DisabledCuesVisibilityProperty); }
            set { SetValue(DisabledCuesVisibilityProperty, value); }
        }

        public Brush FocusBrush
        {
            get { return (Brush)GetValue(FocusBrushProperty); }
            set { SetValue(FocusBrushProperty, value); }
        }

        public Visibility FocusCuesVisibility
        {
            get { return (Visibility)GetValue(FocusCuesVisibilityProperty); }
            set { SetValue(FocusCuesVisibilityProperty, value); }
        }

        internal bool ForceMouseOver
        {
            get { return (bool)GetValue(ForceMouseOverProperty); }
            set { SetValue(ForceMouseOverProperty, value); }
        }

        public string Format
        {
            get { return (string)GetValue(FormatProperty); }
            set { SetValue(FormatProperty, value); }
        }

        public bool HandleUpDownKeys
        {
            get { return (bool)GetValue(HandleUpDownKeysProperty); }
            set { SetValue(HandleUpDownKeysProperty, value); }
        }

        public double Increment
        {
            get { return (double)GetValue(IncrementProperty); }
            set { SetValue(IncrementProperty, value); }
        }

        public int Interval
        {
            get { return (int)GetValue(IntervalProperty); }
            set { SetValue(IntervalProperty, value); }
        }

        public bool IsFocused
        {
            get { return (bool)GetValue(IsFocusedProperty); }
            internal set { SetValue(IsFocusedProperty, value); }
        }

        public bool IsMouseOver
        {
            get { return (bool)GetValue(IsMouseOverProperty); }
            internal set { SetValue(IsMouseOverProperty, value); }
        }

        public bool IsReadOnly
        {
            get { return (bool)GetValue(IsReadOnlyProperty); }
            set { SetValue(IsReadOnlyProperty, value); }
        }

        private bool IsTextUpdateSuspended
        {
            get
            {
                return (this._textUpdateCounter > 0);
            }
        }

        public double Maximum
        {
            get { return (double)GetValue(MaximumProperty); }
            set { SetValue(MaximumProperty, value); }
        }

        public double Minimum
        {
            get { return (double)GetValue(MinimumProperty); }
            set { SetValue(MinimumProperty, value); }
        }

        public Brush MouseOverBrush
        {
            get { return (Brush)GetValue(MouseOverBrushProperty); }
            set { SetValue(MouseOverBrushProperty, value); }
        }

        public Brush PressedBrush
        {
            get { return (Brush)GetValue(PressedBrushProperty); }
            set { SetValue(PressedBrushProperty, value); }
        }

        public RangeValidationMode RangeValidationMode
        {
            get { return (RangeValidationMode)GetValue(RangeValidationModeProperty); }
            set { SetValue(RangeValidationModeProperty, value); }
        }

        public Brush SelectionBackground
        {
            get { return (Brush)GetValue(SelectionBackgroundProperty); }
            set { SetValue(SelectionBackgroundProperty, value); }
        }

        public Brush SelectionForeground
        {
            get { return (Brush)GetValue(SelectionForegroundProperty); }
            set { SetValue(SelectionForegroundProperty, value); }
        }

        public int SelectionLength
        {
            get { return (int)GetValue(SelectionLengthProperty); }
            set { SetValue(SelectionLengthProperty, value); }
        }

        public int SelectionStart
        {
            get { return (int)GetValue(SelectionStartProperty); }
            set { SetValue(SelectionStartProperty, value); }
        }

        public SelectOnFocusCondition SelectOnFocus
        {
            get { return (SelectOnFocusCondition)GetValue(SelectOnFocusProperty); }
            set { SetValue(SelectOnFocusProperty, value); }
        }

        public bool ShowButtons
        {
            get { return (bool)GetValue(ShowButtonsProperty); }
            set { SetValue(ShowButtonsProperty, value); }
        }

        internal string Text
        {
            get
            {
                return this.GetTextValue();
            }
            set { SetValue(TextProperty, value); }
        }

        public TextAlignment TextAlignment
        {
            get { return (TextAlignment)GetValue(TextAlignmentProperty); }
            set { SetValue(TextAlignmentProperty, value); }
        }

        public Style ValidationDecoratorStyle
        {
            get { return (Style)GetValue(ValidationDecoratorStyleProperty); }
            set { SetValue(ValidationDecoratorStyleProperty, value); }
        }

        public double Value
        {
            get { return (double)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

        public object Watermark
        {
            get { return GetValue(WatermarkProperty); }
            set { SetValue(WatermarkProperty, value); }
        }
    }

    public enum RangeValidationMode
    {
        Always,
        AlwaysTruncate,
        OnLostFocus
    }
}
